#include <Utility.hpp>
#include <cstdlib>
#include <Trie.hpp>
#include <algorithm>
#include <utility>

// Gera palavra aleatoria de tamanho 5 e retorna em string
std::string Utility::randomWord(bool insensitive) {
	int qtyLetters = 5;
	char buffer[6];
	for (int i = 0; i < qtyLetters; i++)
		buffer[i] = Trie::convertToChar(rand() % (insensitive ? 26 : 52));
	buffer[qtyLetters] = 0;
	return std::string(buffer);
}

// Gera palavra aleatoria de tamanho 5 (modificando buffer)
void Utility::randomWord(char* buffer) {
	int qtyLetters = 5;
	for (int i = 0; i < qtyLetters; i++)
		buffer[i] = Trie::convertToChar(rand() % 26);
	buffer[qtyLetters] = 0;
}

// Transforma todas as palavras de uma lista em partes menores,
// de tamanho fixo 5 ou menor, caso nao seja possivel dividir
// por 5 extamente
// uma GTrie
// ppieces sera criada, com nos que apontam para as palavras
// originais, em words.
// O vetor qty (previamente criado)
// contera a quantidade de pedacos que cada palavra
// original de mesmo indice possui
// A trie pieces contera os pedacos gerados
void Utility::split(
Trie* pieces,
GTrie<int>* ppieces,
std::vector<std::string>& words,
std::vector<int>& qty) {

	// Incremento normal tera tamanho 5
	int incr = 5;
	for (int i = 0; i < words.size(); i++) {

		// Caso a o tamanho da palavra % 5 seja 1,
		// primeiro incremento tera tamanho 4, de modo que
		// a ultima parte tera tamanho 2, ao inves de 1
		if (words[i].size() > 5 && words[i].size() % 5 == 1)
			incr = 4;

		for (int begin = 0;
			begin < words[i].size();
			begin += incr) {
			int lastp1 = std::min(begin+incr, (int)words[i].size());
			std::string path = 
			words[i].substr(begin, lastp1 - begin);

			ppieces->insert(path, i);
			pieces->insert(path);
			qty[i]++;
			incr = 5;
		}
	}
}
